#pragma once

#ifndef PARMELA_KEYWORD_H
#define PARMELA_KEYWORD_H

#include "parmela_input.h"

namespace lattice
{//order as being in the manual
	class RUN : public keyword_base
	{
	public:
		RUN() 
		{
			keyword = "RUN";
			alias_name="RUN";
			
			parameters.resize(9);

			parameters[0].is_int=true;
			parameters[1].is_int=true;
			parameters[2].is_int=false;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=true;
			parameters[6].is_int=false;
			parameters[7].is_int=false;
			parameters[8].is_int=false;
			
			parameters[0].name="RunNumber";
			parameters[1].name="PrintFlag";
			parameters[2].name="f0";
			parameters[3].name="Z0";
			parameters[4].name="W0";
			parameters[5].name="LinacType";
			parameters[6].name="m(1)c^2";
			parameters[7].name="m(2)c^2";
			parameters[8].name="m(3)c^2";
			
			parameters[0].description="If less than 1000, it will serve as identifying run number. Else, it defines the maximum number of element in beam line, which is default to 1000.";
			parameters[1].description="If non-zero, then Parmela echoes subsequenct input lines to the output file.";
			parameters[2].description="The rf frequency of the linac in MHz";
			parameters[3].description="The initial longitudinal position of the reference particle in cm, the begining of the first element is always z=0";
			parameters[4].description="The initial kinetic energy of the reference particle in MeV";
			parameters[5].description="The LinacType parameter specifies certain types of common linac cavities. Its value on the RUN line sets the default value to use if LinacType = 0 on a CELL line. If you use CField lines to supply actual field values, or if you supply Fourier coefficients on CELL lines (rather than use stored Fourier coefficients), the value of LinacType is unimportant. When using stored sets of Fourier coefficients, set LinacType = 1 for the disk-and-washer structure; 2 for the side-coupled cavity; 6 for the race-track microtron side-coupled cavity.";
			parameters[6].description="The rest mass energy for ParticleType=1 in MeV";
			parameters[7].description="The rest mass energy for ParticleType=2 in MeV";
			parameters[8].description="The rest mass energy for ParticleType=3 in MeV";
		};
	};
	class TITLE : public keyword_base
	{
	public:
		TITLE() 
		{
			keyword = "TITLE";
			alias_name="TITLE";
			
			parameters.resize(1);

			parameters[0].is_int=false;
			
			parameters[0].name="Title";
			
			parameters[0].description="An 80 charactor title for the problem";
		};

		bool set_value(const std::string& value_string)
		{
			parameters[0].prm_string = value_string;
		}

		std::string get_complete_line()
		{
			return "TITLE\n" + parameters[0].prm_string;
		}
	};
	class CATHODE : public keyword_base
	{
	public:
		CATHODE() 
		{
			keyword = "CATHODE";
			alias_name="CATHODE";
			
			parameters.resize(5);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			
			parameters[0].name="0";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="Rcathode";
			parameters[4].name="kT";
			
			parameters[0].description="Length of the cathode will always be 0.";
			parameters[1].description="The radial aperture";
			parameters[2].description="The rf frequency of the linac in MHz";
			parameters[3].description="The radius of curvature in cm of the spherical cathode, positive means that the center of curvature of the cathode is at a positive z location";
			parameters[4].description="The optional cathode temperature in eV, can be used to give the beam a nonzero emittance";
		};
	};
	class DRIFT : public keyword_base
	{
	public:
		DRIFT() 
		{
			keyword = "DRIFT";
			alias_name="DRIFT";
			
			parameters.resize(3);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			
			parameters[0].description="The length of the drift";
			parameters[1].description="The radial aperture";
			parameters[2].description="Output flag";
		};
	};
	class SOLENOID : public keyword_base
	{
	public:
		SOLENOID() 
		{
			keyword = "SOLENOID";
			alias_name="SOLENOID";
			
			parameters.resize(4);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="B";
			
			parameters[0].description="The length of the solenoid in cm";
			parameters[1].description="The radial aperture";
			parameters[2].description="Output flag";
			parameters[3].description="The magneic field in Gauss, more information in TRANSPORT manual";
		};
	};
	class QUAD : public keyword_base
	{
	public:
		QUAD() 
		{
			keyword = "QUAD";
			alias_name="QUAD";
			
			parameters.resize(4);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="B'";
			
			parameters[0].description="The length of the quadrupole in cm";
			parameters[1].description="The radial aperture";
			parameters[2].description="Output flag";
			parameters[3].description="The magneic field gradient in Gauss/cm";
		};
	};
	class ESQUAD : public keyword_base
	{
	public:
		ESQUAD() 
		{
			keyword = "ESQUAD";
			alias_name="ESQUAD";
			
			parameters.resize(5);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="V";
			parameters[4].name="delta-PHI_max";
			
			parameters[0].description="The length of the quadrupole in cm";
			parameters[1].description="The radial aperture and position of the pole tips";
			parameters[2].description="Output flag";
			parameters[3].description="The voltage in kV on the pole tips";
			parameters[4].description="The maximum integration step";
		};
	};
	class STEERER : public keyword_base
	{
	public:
		STEERER() 
		{
			keyword = "STEERER";
			alias_name="STEERER";
			
			parameters.resize(5);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			
			parameters[0].name="0";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="BxL";
			parameters[4].name="ByL";
			
			parameters[0].description="The length of the steerer in always 0";
			parameters[1].description="The radial aperture";
			parameters[2].description="Output flag";
			parameters[3].description="The voltage in kV on the pole tips";
			parameters[4].description="The maximum integration step";
		};
	};
	class BEND : public keyword_base
	{
	public:
		BEND() 
		{
			keyword = "BEND";
			alias_name="BEND";
			
			parameters.resize(14);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=false;
			parameters[6].is_int=false;
			parameters[7].is_int=false;
			parameters[8].is_int=false;
			parameters[9].is_int=false;
			parameters[10].is_int=false;
			parameters[11].is_int=false;
			parameters[12].is_int=false;
			parameters[13].is_int=false;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="Wr";
			parameters[4].name="alpha_r";
			parameters[5].name="beta_1";
			parameters[6].name="beta_2";
			parameters[7].name="psi_1";
			parameters[8].name="psi_2";
			parameters[9].name="Redge1";
			parameters[10].name="Redge2";
			parameters[11].name="K1";
			parameters[12].name="g/2";
			parameters[13].name="K2";
			
			parameters[0].description="The length of the reference trajectory in cm";
			parameters[1].description="The horizontal aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The kinetic energy of the reference particle in MeV";
			parameters[4].description="The angle of bend of the reference trajectory in degree";
			parameters[5].description="The leading edge angle of the dipole in degree";
			parameters[6].description="The tailing edge angle of the dipole in degree";
			parameters[7].description="The fringe field correction angle for the leading edge in degree";
			parameters[8].description="The fringe field correction angle for the tailing edge in degree";
			parameters[9].description="The radius of curvature of the leading pole face edges in cm, zero mean straight edge";
			parameters[10].description="The radius of curvature of the tailing pole face edges in cm, zero mean straight edge";
			parameters[11].description="The integral of the field related to the extent of the fringing field **equations in manual**";
			parameters[12].description="Half gap of the dipole in cm, will be used as vertical aperture, default value is Ra";
			parameters[13].description="The integral of the field related to the extent of the fringing field **equations in manual**";
		};
	};
	class BUNCHER : public keyword_base
	{
	public:
		BUNCHER() 
		{
			keyword = "BUNCHER";
			alias_name="BUNCHER";
			
			parameters.resize(7);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=false;
			parameters[6].is_int=false;
			
			parameters[0].name="0";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="DELTA_Wmax";
			parameters[4].name="fb";
			parameters[5].name="phi_b";
			parameters[6].name="Wb";
			
			parameters[0].description="The length of the buncher is always 0.";
			parameters[1].description="The radial aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The maximum energy gain in MeV";
			parameters[4].description="The buncher frequency in MHz";
			parameters[5].description="The phase of the buncher rf fields with repect to the master clock in degree";
			parameters[6].description="The optional reference energy in MeV, default is current value of the reference particle energy";
		};
	};
	class CHOPPER : public keyword_base
	{
	public:
		CHOPPER() 
		{
			keyword = "CHOPPER";
			alias_name="CHOPPER";
			
			parameters.resize(10);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=false;
			parameters[6].is_int=false;
			parameters[7].is_int=false;
			parameters[8].is_int=false;
			parameters[9].is_int=false;
			
			parameters[0].name="0";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="fc";
			parameters[4].name="phi_c";
			parameters[5].name="DELTA_phi_c";
			parameters[6].name="DELTA_x";
			parameters[7].name="DELTA_y";
			parameters[8].name="Wmin";
			parameters[9].name="Wmax";
			
			parameters[0].description="The length of the chopper is always 0";
			parameters[1].description="The radial aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The frequency of the chopper in MHz";
			parameters[4].description="The phase of the chopper with respect to the master clock in degree";
			parameters[5].description="The half width of the acceptable phase spread for the chopper in degree";
			parameters[6].description="The half width rectangular aperture in cm";
			parameters[7].description="The half width rectangular aperture in cm";
			parameters[8].description="The minimum kinetic energy of the particles passing the chopper";
			parameters[9].description="The maximum kinetic energy of the particles passing the chopper";
		};
	};
	class STRIPPER : public keyword_base
	{
	public:
		STRIPPER() 
		{
			keyword = "STRIPPER";
			alias_name="STRIPPER";
			
			parameters.resize(7);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=true;
			parameters[4].is_int=false;
			parameters[5].is_int=true;
			parameters[6].is_int=true;
			
			parameters[0].name="0";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="FinalCharge";
			parameters[4].name="P";
			parameters[5].name="Charge";
			parameters[6].name="ParticleType";
			
			parameters[0].description="The length of the stripper is always 0.";
			parameters[1].description="The radial aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The final charge state of particles leaving this element, similary to CHARGE keyword the posible value are -127 to 127 including 0";
			parameters[4].description="The probability that particle will be changed to the charge FinalCharge.";
			parameters[5].description="The optional parameter, if specified, only those particles of the specified charge state can be changed to the charge FinalCharge";
			parameters[6].description="The optional parameter, if specified, only those particles of the specified charge state can be changed to the charge FinalCharge";
		};
	};
	class CELL : public keyword_base
	{
	public:
		CELL() 
		{
			keyword = "CELL";
			alias_name="CELL";
			
			parameters.resize(25);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=true;
			parameters[6].is_int=false;
			parameters[7].is_int=true;
			parameters[8].is_int=false;
			parameters[9].is_int=true;
			parameters[10].is_int=false;
			parameters[11].is_int=false;
			parameters[12].is_int=false;
			parameters[13].is_int=false;
			parameters[14].is_int=false;
			parameters[15].is_int=false;
			parameters[16].is_int=false;
			parameters[17].is_int=false;
			parameters[18].is_int=false;
			parameters[19].is_int=false;
			parameters[20].is_int=false;
			parameters[21].is_int=false;
			parameters[22].is_int=false;
			parameters[23].is_int=false;
			parameters[24].is_int=false;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="phi0";
			parameters[4].name="E0";
			parameters[5].name="CellType";
			parameters[6].name="DELTA_PHI_max";
			parameters[7].name="Config";
			parameters[8].name="f_cell";
			parameters[9].name="LinacType";
			parameters[10].name="B";
			parameters[11].name="C1";
			parameters[12].name="C2";
			parameters[13].name="C3";
			parameters[14].name="C4";
			parameters[15].name="C5";
			parameters[16].name="C6";
			parameters[17].name="C7";
			parameters[18].name="C8";
			parameters[19].name="C9";
			parameters[20].name="C10";
			parameters[21].name="C11";
			parameters[22].name="C12";
			parameters[23].name="C13";
			parameters[24].name="C14";
			
			parameters[0].description="The length of the element in cm";
			parameters[1].description="The radial aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The phase of the cell with respect to the master clock in degree";
			parameters[4].description="The average axial electric field in the cell in MV/m";
			parameters[5].description="The index that identifies the rf field data, should be unique for each data";
			parameters[6].description="The maximum integration step size";
			parameters[7].description="The specifier for the cell field, read manual";
			parameters[8].description="The frequency of the cell in MHz";
			parameters[9].description="Type of linac cavity, read manual";
			parameters[10].description="The optional magnetic field specifies a hard-edged, constant-field solenoid field for this cell.";
			parameters[11].description="The Fourier coefficient for the field expansion, see manual";
			parameters[12].description="The Fourier coefficient for the field expansion, see manual";
			parameters[13].description="The Fourier coefficient for the field expansion, see manual";
			parameters[14].description="The Fourier coefficient for the field expansion, see manual";
			parameters[15].description="The Fourier coefficient for the field expansion, see manual";
			parameters[16].description="The Fourier coefficient for the field expansion, see manual";
			parameters[17].description="The Fourier coefficient for the field expansion, see manual";
			parameters[18].description="The Fourier coefficient for the field expansion, see manual";
			parameters[19].description="The Fourier coefficient for the field expansion, see manual";
			parameters[20].description="The Fourier coefficient for the field expansion, see manual";
			parameters[21].description="The Fourier coefficient for the field expansion, see manual";
			parameters[22].description="The Fourier coefficient for the field expansion, see manual";
			parameters[23].description="The Fourier coefficient for the field expansion, see manual";
			parameters[24].description="The Fourier coefficient for the field expansion, see manual";
		};
	};
	class CELL2 : public keyword_base
	{
	public:
		CELL2() 
		{
			keyword = "CELL2";
			alias_name="CELL2";
			
			parameters.resize(25);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=true;
			parameters[6].is_int=false;
			parameters[7].is_int=false;
			parameters[8].is_int=false;
			parameters[9].is_int=true;
			parameters[10].is_int=false;
			parameters[11].is_int=true;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="phi01";
			parameters[4].name="E01";
			parameters[5].name="CellType1";
			parameters[6].name="f_cell1";
			parameters[7].name="phi02";
			parameters[8].name="E02";
			parameters[9].name="CellType2";
			parameters[10].name="f_cell2";
			parameters[11].name="Config";
			
			parameters[0].description="The length of the element in cm";
			parameters[1].description="The radial aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The phase of the cell with respect to the master clock in degree";
			parameters[4].description="The average axial electric field in the cell in MV/m";
			parameters[5].description="The index that identifies the rf field data, should be unique for each data";
			parameters[6].description="The frequency of the cell in MHz";
			parameters[7].description="The phase of the cell with respect to the master clock in degree";
			parameters[8].description="The average axial electric field in the cell in MV/m";
			parameters[9].description="The index that identifies the rf field data, should be unique for each data";
			parameters[10].description="The frequency of the cell in MHz";
			parameters[11].description="The specifier for the cell field, read manual";
		};
	};
	class DTCELL : public keyword_base
	{
	public:
		DTCELL() 
		{
			keyword = "DTCELL";
			alias_name="DTCELL";
			
			parameters.resize(25);

			parameters[0].is_int=false;
			parameters[1].is_int=false;
			parameters[2].is_int=true;
			parameters[3].is_int=false;
			parameters[4].is_int=false;
			parameters[5].is_int=true;
			parameters[6].is_int=false;
			parameters[7].is_int=true;
			parameters[8].is_int=true;
			parameters[9].is_int=false;
			parameters[10].is_int=false;
			parameters[11].is_int=false;
			parameters[12].is_int=false;
			parameters[13].is_int=false;
			parameters[14].is_int=false;
			parameters[15].is_int=false;
			parameters[16].is_int=false;
			parameters[17].is_int=false;
			parameters[18].is_int=false;
			parameters[19].is_int=false;
			parameters[20].is_int=false;
			parameters[21].is_int=false;
			parameters[22].is_int=false;
			parameters[23].is_int=false;
			parameters[24].is_int=false;
			
			parameters[0].name="L";
			parameters[1].name="Ra";
			parameters[2].name="OutputFlag";
			parameters[3].name="phi0";
			parameters[4].name="E0";
			parameters[5].name="CellType";
			parameters[6].name="DELTA_PHI_max";
			parameters[7].name="Config";
			parameters[8].name="QuadOption";
			parameters[9].name="Lquad";
			parameters[10].name="B'";
			parameters[11].name="C1";
			parameters[12].name="C2";
			parameters[13].name="C3";
			parameters[14].name="C4";
			parameters[15].name="C5";
			parameters[16].name="C6";
			parameters[17].name="C7";
			parameters[18].name="C8";
			parameters[19].name="C9";
			parameters[20].name="C10";
			parameters[21].name="C11";
			parameters[22].name="C12";
			parameters[23].name="C13";
			parameters[24].name="C14";
			
			parameters[0].description="The length of the element in cm";
			parameters[1].description="The radial aperture in cm";
			parameters[2].description="Output flag";
			parameters[3].description="The phase of the cell with respect to the master clock in degree";
			parameters[4].description="The average axial electric field in the cell in MV/m";
			parameters[5].description="The index that identifies the rf field data, should be unique for each data";
			parameters[6].description="The maximum integration step size";
			parameters[7].description="The specifier for the cell field, read manual";
			parameters[8].description="Option for quadrupole magnet, read manual";
			parameters[9].description="The length of the quadrupole magnet";
			parameters[10].description="The magneic field gradient in Gauss/cm";
			parameters[11].description="The Fourier coefficient for the field expansion, see manual";
			parameters[12].description="The Fourier coefficient for the field expansion, see manual";
			parameters[13].description="The Fourier coefficient for the field expansion, see manual";
			parameters[14].description="The Fourier coefficient for the field expansion, see manual";
			parameters[15].description="The Fourier coefficient for the field expansion, see manual";
			parameters[16].description="The Fourier coefficient for the field expansion, see manual";
			parameters[17].description="The Fourier coefficient for the field expansion, see manual";
			parameters[18].description="The Fourier coefficient for the field expansion, see manual";
			parameters[19].description="The Fourier coefficient for the field expansion, see manual";
			parameters[20].description="The Fourier coefficient for the field expansion, see manual";
			parameters[21].description="The Fourier coefficient for the field expansion, see manual";
			parameters[22].description="The Fourier coefficient for the field expansion, see manual";
			parameters[23].description="The Fourier coefficient for the field expansion, see manual";
			parameters[24].description="The Fourier coefficient for the field expansion, see manual";
		};
	};


};









#endif //PARMELA_KEYWORD_H